package com.meshnetics.gb.util;

import java.nio.ByteBuffer;

/**
 * @author Sergey Klimenko (sklimenko@meshnetics.com)
 */
public final class ToStringUtil {
    private static final int SHORT_MASK = 0xffff;

    private ToStringUtil() {
    }

    public static String toString(byte[] bytes) {
        if(bytes == null) {
            return "null";
        } else {
            return toString(bytes, 0, bytes.length);
        }
    }

    public static String toString(byte[] bytes, int offset, int length) {
        // 6 for length and '[', ']' (we shouldn't have arrays longer than 256 bytes)
        // 2+2+i is '0x', hex code of byte (2 symbols always) and ' ' (space)
        StringBuffer sb = new StringBuffer(6 + length * (2 + 2 + 1));
        sb.append(length).append('[');
        final int l = offset + length;
        for (int i = offset; i < l && i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i]);
            sb.append('0').append('x');
            if (hex.length() > 2) { // was negative byte, first 6 symbols are FFFFFF - omitting them
                sb.append(hex.toUpperCase(), hex.length() - 2, hex.length());
            } else if (hex.length() == 1) {
                sb.append('0');
                sb.append(hex.toUpperCase());
            } else {
                sb.append(hex.toUpperCase());
            }
            if (i + 1 != l) {
                sb.append(' ');
            }
        }
        return sb.append(']').toString();
    }

    public static String toCompactString(byte[] bytes) {
        if(bytes == null) {
            return "null";
        } else {
            return toCompactString(bytes, 0, bytes.length);
        }
    }

    public static String toCompactString(byte[] bytes, int offset, int length) {
        if (bytes == null) {
            return "null";
        }

        if (length == 0) {
            return "[empty]";
        }

        int maxLength = (bytes.length - offset);

        if (length > maxLength) {
            length = maxLength;
        }
        StringBuffer sb = new StringBuffer(length * 3 - 1);
        final int l = offset + length;

        for (int i = offset; i < l; i++) {
            String hex = Integer.toHexString(bytes[i]);

            if (hex.length() > 2) { // was negative byte, first 6 symbols are FFFFFF - omitting them
                sb.append(hex.toUpperCase(), hex.length() - 2, hex.length());
            } else if (hex.length() == 1) {
                sb.append('0');
                sb.append(hex.toUpperCase());
            } else {
                sb.append(hex.toUpperCase());
            }
            if (i != (l - 1)) {
                sb.append(' ');
            }
        }
        return sb.toString();
    }

    public static String toString(ByteBuffer bb) {
        return toString(bb.array(), bb.position(), bb.remaining());
    }

    public static String toHexString(Short sh) {
        if (sh == null) {
            return "short null";
        } else {
            return toHexString(sh.shortValue());
        }
    }

    public static String toHexString(short sh) {
        return "short 0x" + Integer.toHexString(sh & SHORT_MASK);
    }

    public static String toHexString(Long ln) {
        if (ln == null) {
            return "long null";
        } else {
            return toHexString(ln.longValue());
        }
    }

    public static String toHexString(long ln) {
        return "long 0x" + Long.toHexString(ln);
    }

    public static String getSimpleName(Class clazz) {
        String s = clazz.getName();
        return s.substring(s.lastIndexOf('.') + 1);
    }
}
